import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Collection;
import java.util.Scanner;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.filefilter.FalseFileFilter;
import org.apache.commons.io.filefilter.TrueFileFilter;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import org.eclipse.jetty.io.RuntimeIOException;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ResourceHandler;

public abstract class KAPlayerUtils {

    public static final String BASE_DIR = System.getProperty("user.dir");
    
    protected static final File WEB_BASE_DIR = new File(BASE_DIR, "web");

    protected static final File AUDIO_FILE_DIR = new File(BASE_DIR, "web/audios");

    protected static final class WebServer {

        public static final WebServer DEFAULT_WEB_SERVER = new WebServer(8121, "/web");

        private Server webServer;

        public WebServer(int port, String webDirectory) {
            // Initialize web server
            webServer = new Server(port);
            ResourceHandler resourceHandler = new ResourceHandler();
            resourceHandler.setResourceBase(BASE_DIR + webDirectory);
            webServer.setHandler(resourceHandler);
        }

        public void start() throws Exception {
            if (webServer.isStopped()) {
                webServer.start();
            }
        }

        public void stop() throws Exception {
            webServer.stop();
            webServer.destroy();
        }

    }

    public static void export(File directory, String playlistXml) throws Exception {
        // List all audio files
        Collection<File> audioFiles = FileUtils.listFiles(directory, new String[] {
                "ogg", "mpeg-1", "mpeg-2", "mp3", "wav", "webm"
        }, true);

        // Create audio document
        Element rootElem = DocumentHelper.createElement("playlist");
        Document audioDoc = DocumentHelper.createDocument(rootElem);
        // Delete audio files
        FileUtils.deleteDirectory(AUDIO_FILE_DIR);

        if (audioFiles != null && !audioFiles.isEmpty()) {
            // Sort files by modified
            audioFiles.stream().sorted((File audioFile1, File audioFile2) ->
                Long.compare(audioFile2.lastModified(), audioFile1.lastModified())
            ).forEach(audioFile -> {
                try {
                    FileUtils.copyFileToDirectory(audioFile, AUDIO_FILE_DIR);
                } catch (IOException e) {
                    throw new RuntimeIOException(e);
                }
            });
            // List audio files
            audioFiles = FileUtils.listFiles(AUDIO_FILE_DIR, TrueFileFilter.INSTANCE, FalseFileFilter.INSTANCE);

            // Add audio Elements
            for (File audioFile : audioFiles) {
                String audioName = FilenameUtils.getBaseName(audioFile.getName());
                String audioUrl = FilenameUtils.separatorsToUnix(audioFile.getPath().
                        substring(WEB_BASE_DIR.getPath().length()));

                Element musicElem = rootElem.addElement("music");
                musicElem.addElement("name").setText(audioName);
                musicElem.addElement("url").setText(audioUrl);
            }
        }

        // Format and output audio document
        OutputFormat xmlFormat = OutputFormat.createPrettyPrint();
        xmlFormat.setIndent("    ");
        xmlFormat.setNewLineAfterDeclaration(false);
        XMLWriter xmlWriter = null;
        try {
            xmlWriter = new XMLWriter(new FileOutputStream(new File(BASE_DIR, playlistXml)), xmlFormat);
            xmlWriter.write(audioDoc);
        } finally {
            if (xmlWriter != null) {
                xmlWriter.close();
            }
        }
    }

    public static void main(String[] args) {
        System.out.println("========== START ==========");

        try (Scanner scanner = new Scanner(System.in)) {
            // Export audio playlist
            System.out.print("Do you want to export audio files? (yes / enter others to continue): ");
            if ("yes".equals(scanner.nextLine())) {
                System.out.print("Audio files directory: ");
                KAPlayerUtils.export(new File(scanner.nextLine()), "/web/xml/playlist.xml");
            }
            // Start web server
            KAPlayerUtils.WebServer webServer = KAPlayerUtils.WebServer.DEFAULT_WEB_SERVER;
            webServer.start();
            System.out.println("Web server url is 'http://localhost:8121/', you can stop the web server by entering 'yes'.");
            while (true) {
                if ("yes".equals(scanner.nextLine())) {
                    break;
                }
            }
            webServer.stop();
        } catch (Exception e) {
            e.printStackTrace();
        }

        System.out.println("=========== END ===========");
    }

}
